#ifndef AT_LEXER_H
#define AT_LEXER_H
#include <stdint.h>

#define AT_LEXER_MAX_STREAM_LEN 4096
#define AT_DELIMITER 0x0D0A /** "\r\n" */


typedef enum {
    AT_LEXER_STATE_HEAD,
    AT_LEXER_STATE_BODY,
    AT_LEXER_STATE_TAIL,
    AT_LEXER_STATE_SEND_READY,
    AT_LEXER_STATE_CUSTOM,
    AT_LEXER_STATE_MAX
}AT_LEXER_STATE;


typedef AT_LEXER_STATE (*PF_AT_LEXER_STATE)(uint8_t);

#pragma anon_unions
typedef struct _AT_HANDLER{
	const char *pname;
	uint32_t size;
    union{
        void (*nb_info_handler)(uint8_t *pdata,uint32_t len);
        int32_t (*nb_info_handler_any)(uint8_t *pdata,uint32_t len);
    };
    AT_LEXER_STATE (*pf_at_lexer_state)(uint8_t);
}AT_HANDLER;

#define AT_HANDLER_GENERAL_DEF(_prefix_,_handler_) {_prefix_,sizeof(_prefix_) - 1,_handler_,NULL}
#define AT_HANDLER_SPECIAL_DEF(_prefix_,_handler_,_next_state_) {_prefix_,sizeof(_prefix_) - 1,_handler_,_next_state_}
#define AT_HANDLER_ANY(_handler_) {.pname = "",.size = 0,.nb_info_handler_any = _handler_,.pf_at_lexer_state = NULL}


typedef PF_AT_LEXER_STATE (*AT_LEXER_HANDLER)(uint8_t *,uint32_t);

extern void at_lexer_execute(uint8_t data);

extern void at_lexer_handler_set(AT_LEXER_HANDLER pf_handler);
extern AT_LEXER_HANDLER at_lexer_handler_get(void);

typedef struct _BYTES{
    uint8_t *pdata;
    uint32_t len;
}BYTES;

extern int at_match(BYTES *psrc, const char *ppattern, ...);

#endif
